package com.bcx.wind.workflow.imp.cmd.managercmd;

import com.bcx.wind.workflow.access.QueryFilter;
import com.bcx.wind.workflow.core.constant.TaskLevel;
import com.bcx.wind.workflow.core.constant.TaskStatus;
import com.bcx.wind.workflow.entity.WindActHistory;
import com.bcx.wind.workflow.entity.WindTask;
import com.bcx.wind.workflow.entity.WindTaskActor;
import com.bcx.wind.workflow.interceptor.Command;
import com.bcx.wind.workflow.interceptor.CommandContext;
import com.bcx.wind.workflow.pojo.WindUser;
import com.bcx.wind.workflow.support.Assert;
import com.bcx.wind.workflow.support.JsonHelper;
import com.bcx.wind.workflow.support.ObjectHelper;
import com.bcx.wind.workflow.support.TimeHelper;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import static com.bcx.wind.workflow.message.ErrorCode.CHILD_TASK_OPERATOR_IS_NULL;
import static com.bcx.wind.workflow.message.ErrorCode.MAIN_TASK_IS_NULL;
import static com.bcx.wind.workflow.message.ErrorCode.TASK_NOT_SUPPORT_OPERATE;


/**
 * 添加子任务命令
 *
 * @author zhanglei
 */
public class CreateChildTaskCommand implements Command<List<WindTask>> {

    /**
     * 主任务ID
     */
    private String taskId;

    /**
     * 任务操作人
     */
    private List<WindUser> windUserList;

    /**
     * 当前用户
     */
    private WindUser user;

    /**
     * 主任务
     */
    private WindTask mainTask;


    private CommandContext commandContext;

    public CreateChildTaskCommand(String taskId, List<WindUser> windUsers,WindUser user){
        this.taskId = taskId;
        this.windUserList = windUsers;
        this.user = user;
    }


    @Override
    public List<WindTask> executor(CommandContext context) {
        try{
            this.commandContext = context;
            return execute();

        }catch (Exception e){
            context.log(e);
            return null;
        }
    }

    private List<WindTask> execute() {
        //校验参数
        checkArgs();

        //返回值
        List<WindTask> result = new LinkedList<>();

        //执行添加
        for(WindUser windUser : this.windUserList){

            //添加新任务
            String newTaskId = ObjectHelper.primaryKey();
            WindTask newTask = buildNewTask().setId(newTaskId)
                    .setParentId(this.taskId)
                    .setTaskLevel(TaskLevel.child.name())
                    .setCreateUser(user().proxyUserId());
            this.commandContext.access().insertTaskInstance(newTask);

            //添加子任务操作人
            WindTaskActor actor = new WindTaskActor()
                    .setTaskId(newTaskId)
                    .setActorId(windUser.getUserId());
            this.commandContext.access().insertTaskActor(actor);

            //添加历史
            addHistory(newTask,windUser);
            result.add(newTask);
        }

        return result;
    }



    /**
     * 添加子任务历史
     */
    private void  addHistory(WindTask windTask,WindUser windUser){
        //查询主任务历史
        QueryFilter filter = new QueryFilter()
                .setTaskId(this.taskId);
        List<WindActHistory> actHistories = commandContext.access().selectActiveHistoryList(filter);
        if(!ObjectHelper.isEmpty(actHistories)){

            WindActHistory history = actHistories.get(0);
            WindActHistory act = new WindActHistory()
                    .setId(ObjectHelper.primaryKey())
                    .setApproveUserVariable(JsonHelper.toJson(Collections.singleton(windUser)))
                    .setCreateTime(TimeHelper.nowDate())
                    .setOrderId(windTask.getOrderId())
                    .setProcessDisplayName(history.getProcessDisplayName())
                    .setProcessId(history.getProcessId())
                    .setProcessName(history.getProcessName())
                    .setSystem(history.getSystem())
                    .setTaskCreateUser(windTask.getCreateUser())
                    .setTaskId(windTask.getId())
                    .setTaskDisplayName(windTask.getDisplayName())
                    .setTaskName(windTask.getTaskName())
                    .setTaskType(windTask.getTaskType())
                    .setTaskLevel(TaskLevel.child.name())
                    .setTaskParentId(this.taskId);
            this.commandContext.access().insertActiveHistory(act);
        }

    }


    private void checkArgs(){
        //校验任务
        Assert.notEmptyError(MAIN_TASK_IS_NULL,this.taskId);
        QueryFilter filter = new QueryFilter()
                .setTaskId(this.taskId)
                .setTaskLevel(TaskLevel.main.name());
        List<WindTask> windTasks = this.commandContext.access().selectTaskInstanceList(filter);
        Assert.notEmptyError(MAIN_TASK_IS_NULL,windTasks);
        Assert.isTrueError(TASK_NOT_SUPPORT_OPERATE,!TaskStatus.run.name().equals(windTasks.get(0).getStatus()));
        this.mainTask = windTasks.get(0);

        //校验审批人
        Assert.notEmptyError(CHILD_TASK_OPERATOR_IS_NULL,this.windUserList);
        for(WindUser windUser : this.windUserList){
            Assert.notEmptyError(CHILD_TASK_OPERATOR_IS_NULL,windUser.getUserId());
        }
    }

    private WindTask buildNewTask(){
        return this.mainTask.clone();
    }


    private WindUser user(){
        return this.user == null ? new WindUser()
                .setUserId("admin")
                .setUserName("管理员") : this.user;
    }
}
